home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / mus / edit / AlgoRhythms.lha / AlgoRhythms / Source / voices.c < prev    next >
C/C++ Source or Header  |  1994-11-25  |  11KB  |  366 lines

  1. /* voices.c
  2.     Copyright (c) 1993 by Thomas E. Janzen
  3.     All Rights Reserved
  4.  
  5.     THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
  6.     BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
  7.     CHANGES FOR FREE DISTRIBUTION.  NO TITLE TO AND OWNERSHIP OF THE
  8.     SOFTWARE IS HEREBY TRANSFERRED.  THOMAS E. JANZEN ASSUMES NO 
  9.     RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
  10.     
  11.     Thomas E. Janzen
  12.     208A Olde Derby Road
  13.     Norwood, MA  02062-1761
  14.     (617)769-7733
  15.  
  16. **  FACILITY:
  17. **
  18. **    AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
  19. **    compiled with SAS/C Amiga Compiler 6.50 
  20. **
  21. **  ABSTRACT:
  22. **
  23. **    voices.c supports gadgets (using GadTools) for controlling one
  24. **    voice's set up at a time.
  25. **
  26. **  AUTHORS: Thomas E. Janzen
  27. **
  28. **  CREATION DATE:    23-OCT-1993
  29. **
  30. **  MODIFICATION HISTORY:
  31. **    DATE    NAME    DESCRIPTION
  32. **    1 JAN 93 TEJ    New for V3.0
  33. **-- 
  34. */
  35.  
  36. #define INTUI_V36_NAMES_ONLY
  37.  
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <ctype.h>
  41. #include <string.h>
  42. #include <exec/types.h>
  43. #include <exec/nodes.h>
  44. #include <intuition/intuition.h>
  45. #include <libraries/gadtools.h>
  46.  
  47. #include <clib/exec_protos.h>
  48. #include <clib/graphics_protos.h>
  49. #include <clib/intuition_protos.h>
  50. #include <clib/gadtools_protos.h>
  51. #include <clib/utility_protos.h>
  52. #include <clib/dos_protos.h>
  53. #include <proto/graphics.h> 
  54. #include <proto/intuition.h>
  55. #include <proto/gadtools.h>
  56.  
  57. #include "window.h"
  58. #include "voices.h"
  59. #include "algorhythms.h"
  60. #include "pitchnames.h"
  61.  
  62. #define C_MELODY_X      (100)
  63. #define C_MELODY_Y      (24)
  64. #define C_MIDI_X        (100)
  65. #define C_MIDI_Y        (36)
  66. #define C_LOW_X         (100)
  67. #define C_LOW_Y         (60)
  68. #define C_HIGH_X        (100)
  69. #define C_HIGH_Y        (48)
  70. #define C_VOICE_X       (100)
  71. #define C_VOICE_Y       (12)
  72. #define C_CHAN_X        (205)
  73. #define C_CHAN_Y        (24)
  74. #define GAD_VOICE       (0)
  75. #define GAD_CHAN        (1)
  76. #define GAD_MELODY      (2)
  77. #define GAD_LOW_NOTE    (3)
  78. #define GAD_HIGH_NOTE   (4)
  79. #define GAD_MIDI        (5)
  80. #define GAD_LAST        (6)
  81.  
  82. #define C_INNER_WINDOW (625)
  83.  
  84. static char 
  85.         *melody_str[]  = {"Random", "Walking", NULL}, 
  86.         *midi_str[]     = {"Midi", "Audio", NULL},
  87.         *voice_str[]    = { "1", "2", "3", "4", "5", "6", "7", "8", "9", 
  88.                             "10", "11", "12", "13", "14", "15", "16", 
  89.                             "17", "18", "19", "20", NULL}; 
  90. static struct Node chan_nodes[18] 
  91.     = {{&chan_nodes[1],  NULL, 0, 0, NULL},
  92.        {&chan_nodes[2],  &chan_nodes[0],  0, 0, " 1"},
  93.        {&chan_nodes[3],  &chan_nodes[1],  0, 0, " 2"},
  94.        {&chan_nodes[4],  &chan_nodes[2],  0, 0, " 3"},
  95.        {&chan_nodes[5],  &chan_nodes[3],  0, 0, " 4"},
  96.        {&chan_nodes[6],  &chan_nodes[4],  0, 0, " 5"},
  97.        {&chan_nodes[7],  &chan_nodes[5],  0, 0, " 6"},
  98.        {&chan_nodes[8],  &chan_nodes[6],  0, 0, " 7"},
  99.        {&chan_nodes[9],  &chan_nodes[7],  0, 0, " 8"},
  100.        {&chan_nodes[10], &chan_nodes[8],  0, 0, " 9"},
  101.        {&chan_nodes[11], &chan_nodes[9],  0, 0, "10"},
  102.        {&chan_nodes[12], &chan_nodes[10], 0, 0, "11"},
  103.        {&chan_nodes[13], &chan_nodes[11], 0, 0, "12"},
  104.        {&chan_nodes[14], &chan_nodes[12], 0, 0, "13"},
  105.        {&chan_nodes[15], &chan_nodes[13], 0, 0, "14"},
  106.        {&chan_nodes[16], &chan_nodes[14], 0, 0, "15"},
  107.        {&chan_nodes[17], &chan_nodes[15], 0, 0, "16"},
  108.        {NULL,            &chan_nodes[16], 0, 0, NULL}};
  109.  
  110. static struct Window *voice_wind = NULL;
  111. static struct Gadget    *glist = NULL, 
  112.                         *voice_gads[GAD_LAST];
  113. ULONG voices_mask = 0;
  114.  
  115. static int current_voice = 0;
  116.  
  117. static struct Gadget *create_voice_gadgets(UWORD topborder);
  118. static void voice_event(struct Gadget *gad, UWORD code, 
  119.     NOTE_EVENT_TYPE *events);
  120.  
  121. static void voice_event(struct Gadget *gad, UWORD code, 
  122.     NOTE_EVENT_TYPE *events)
  123. {
  124.     switch (gad->GadgetID)
  125.     {
  126.         case GAD_VOICE:
  127.             current_voice = code;
  128.             set_voice_gadgets(events);
  129.             break;
  130.         case GAD_CHAN:
  131.             events[current_voice].nv_i_channel = code;
  132.             break;
  133.         case GAD_MELODY:
  134.             events[current_voice].nv_i_walking = code;
  135.             break;
  136.         case GAD_LOW_NOTE:
  137.             events[current_voice].nv_i_low_pitch 
  138.             = pitch_to_midi
  139.             (((struct StringInfo *)(gad->SpecialInfo))->Buffer);
  140.             break;
  141.         case GAD_HIGH_NOTE:
  142.             events[current_voice].nv_i_high_pitch 
  143.             = pitch_to_midi(((struct StringInfo *)
  144.             (gad->SpecialInfo))->Buffer);
  145.             break;
  146.         case GAD_MIDI:
  147.             events[current_voice].nv_i_audio = code;
  148.             break;
  149.         default:
  150.             break;
  151.     }
  152.     return;
  153. }
  154.  
  155. static struct Gadget *create_voice_gadgets(UWORD topborder)
  156. {
  157.  
  158.     auto struct TagItem high_low_items[] ={{GTST_String, (ULONG)"A#1"}, 
  159.         {GTST_MaxChars, 10}, {TAG_END, 0L}};
  160.     auto struct NewGadget ng;
  161.     auto struct Gadget *gad;
  162.  
  163.     gad = CreateContext(&glist);
  164.  
  165.     ng.ng_Height = 12;
  166.     ng.ng_TextAttr = &font_choice;
  167.     ng.ng_VisualInfo = vi;
  168.  
  169.     /*
  170.     ** Set up Voice selection
  171.     */
  172.     ng.ng_LeftEdge = C_VOICE_X;
  173.     ng.ng_TopEdge = C_VOICE_Y;
  174.     ng.ng_Width = 100;
  175.     ng.ng_Height = 12;
  176.     ng.ng_GadgetText = "VOICE";
  177.     ng.ng_GadgetID = GAD_VOICE;
  178.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT;
  179.     voice_gads[GAD_VOICE] 
  180.         = gad
  181.         = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, voice_str,
  182.         TAG_END); 
  183.     /*
  184.     ** Set up chan list
  185.     */
  186.     ng.ng_LeftEdge = C_CHAN_X;
  187.     ng.ng_TopEdge = C_CHAN_Y;
  188.     ng.ng_Width = 65;
  189.     ng.ng_Height = 52;
  190.     ng.ng_GadgetText = "Channel";
  191.     ng.ng_GadgetID = GAD_CHAN;
  192.     ng.ng_Flags = PLACETEXT_ABOVE;
  193.     voice_gads[GAD_CHAN] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
  194.         GTLV_Labels, chan_nodes, GTLV_ShowSelected, NULL, TAG_END); 
  195.     /*
  196.     ** Set up Melody random/walking
  197.     */
  198.     ng.ng_LeftEdge = C_MELODY_X;
  199.     ng.ng_TopEdge = C_MELODY_Y;
  200.     ng.ng_Width = 100;
  201.     ng.ng_Height = 12;
  202.     ng.ng_GadgetText = "Melody";
  203.     ng.ng_Flags = PLACETEXT_LEFT;
  204.     ng.ng_GadgetID = GAD_MELODY;
  205.     voice_gads[GAD_MELODY] 
  206.         = gad
  207.         = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, melody_str,
  208.         TAG_END, 0L); 
  209.     /*
  210.     ** Set up low note
  211.     */
  212.     ng.ng_LeftEdge = C_LOW_X;
  213.     ng.ng_TopEdge = C_LOW_Y;
  214.     ng.ng_Width = 100;
  215.     ng.ng_GadgetText = "Low Note";
  216.     ng.ng_GadgetID = GAD_LOW_NOTE;
  217.     ng.ng_Flags = PLACETEXT_LEFT;
  218.     voice_gads[GAD_LOW_NOTE] = gad 
  219.         = CreateGadgetA(STRING_KIND, gad, &ng, high_low_items); 
  220.     /*
  221.     ** Set up high note
  222.     */
  223.     ng.ng_LeftEdge = C_HIGH_X;
  224.     ng.ng_TopEdge = C_HIGH_Y;
  225.     ng.ng_Width = 100;
  226.     ng.ng_GadgetText = "High Note";
  227.     ng.ng_Flags = PLACETEXT_LEFT;
  228.     ng.ng_GadgetID = GAD_HIGH_NOTE;
  229.     voice_gads[GAD_HIGH_NOTE] = gad 
  230.         = CreateGadgetA(STRING_KIND, gad, &ng, high_low_items); 
  231.  
  232.     /*
  233.     ** Set up Audio/MIDI
  234.     */
  235.     ng.ng_LeftEdge = C_MIDI_X;
  236.     ng.ng_TopEdge = C_MIDI_Y;
  237.     ng.ng_Width = 100;
  238.     ng.ng_GadgetText = "MIDI/Audio";
  239.     ng.ng_GadgetID = GAD_MIDI;
  240.     ng.ng_Flags = PLACETEXT_LEFT;
  241.     voice_gads[GAD_MIDI] 
  242.         = gad
  243.         = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, midi_str,
  244.         TAG_END); 
  245.     return gad;
  246. }
  247.  
  248. int process_voice_events(NOTE_EVENT_TYPE *chairs)
  249. {
  250.     auto int result = 0,
  251.              Closing = FALSE;
  252.     auto ULONG imsgClass;
  253.     auto UWORD imsgCode;
  254.     auto struct Gadget *gad;
  255.     auto struct IntuiMessage *imsg;
  256.     
  257.     while (imsg = GT_GetIMsg(voice_wind->UserPort))
  258.     {
  259.         gad = (struct Gadget *)imsg->IAddress;
  260.         imsgClass = imsg->Class;
  261.         imsgCode = imsg->Code;
  262.         GT_ReplyIMsg(imsg);
  263.         switch(imsgClass)
  264.         {
  265.             case IDCMP_CLOSEWINDOW:
  266.                 Closing = TRUE;
  267.                 break;
  268.             case IDCMP_GADGETDOWN:
  269.             case IDCMP_MOUSEMOVE:
  270.             case IDCMP_GADGETUP:
  271.                 voice_event(gad, imsgCode, chairs);
  272.                 result = 1;
  273.                 break;
  274.             case IDCMP_REFRESHWINDOW:
  275.                 GT_BeginRefresh(voice_wind);
  276.                 GT_RefreshWindow(voice_wind, NULL);
  277.                 GT_EndRefresh(voice_wind, TRUE);
  278.                 break;
  279.         }
  280.     }
  281.     if (Closing)
  282.     {
  283.         close_voices();
  284.     }
  285.     return result;
  286. }
  287.  
  288. void open_voices_window(void)
  289. {
  290.     auto UWORD   topborder;
  291.     
  292.     if (voice_wind != NULL) 
  293.     {
  294.         return;
  295.     }
  296.     topborder   = main_screen->WBorTop 
  297.                 + (main_screen->Font->ta_YSize + 1);
  298.     if (NULL == create_voice_gadgets(topborder))
  299.     {
  300.         ;
  301.     }
  302.     else
  303.     {
  304.         if (NULL == (voice_wind = OpenWindowTags(NULL,
  305.             WA_Title, "VOICE",
  306.             WA_Left, 200L,
  307.             WA_Gadgets, glist, WA_AutoAdjust, TRUE,
  308.             WA_Width, 276, WA_MinWidth, 290,
  309.             WA_InnerHeight, 61, WA_MinHeight, 71,
  310.             WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  311.             WA_Activate, TRUE,
  312. #if 0
  313.             WA_CloseGadget, TRUE,
  314. #endif
  315.             WA_SimpleRefresh, TRUE,
  316.             WA_IDCMP, /* IDCMP_CLOSEWINDOW | */ IDCMP_REFRESHWINDOW 
  317.             | STRINGIDCMP | BUTTONIDCMP | LISTVIEWIDCMP,
  318.             WA_CustomScreen, main_screen, TAG_END)))
  319.         {
  320.           ;
  321.         }
  322.         else
  323.         {
  324.             GT_RefreshWindow(voice_wind, NULL);
  325.             voices_mask = 1 << voice_wind->UserPort->mp_SigBit;
  326.         }
  327.     }
  328.     return;
  329. }
  330.  
  331. void close_voices(void)
  332. {
  333.     RemoveGList(voice_wind, glist, -1);
  334.     CloseWindowSafely(voice_wind);
  335.     voice_wind = NULL;
  336.     FreeGadgets(glist);
  337.     glist = NULL;
  338.     return;
  339. }
  340.  
  341. void set_voice_gadgets(NOTE_EVENT_TYPE *chairs)
  342. {
  343.     auto char temp_str[80];
  344.  
  345.     GT_SetGadgetAttrs(voice_gads[GAD_CHAN], voice_wind, NULL,
  346.         GTLV_Selected, chairs[current_voice].nv_i_channel, TAG_END, 0L);
  347.     GT_SetGadgetAttrs(voice_gads[GAD_MELODY], voice_wind, NULL,
  348.         GTCY_Active, chairs[current_voice].nv_i_walking, TAG_END, 0L);
  349.     midi_to_pitch(chairs[current_voice].nv_i_low_pitch, temp_str); 
  350.     GT_SetGadgetAttrs(voice_gads[GAD_LOW_NOTE], voice_wind, NULL,
  351.         GTST_String, temp_str, TAG_END, 0L);
  352.     midi_to_pitch(chairs[current_voice].nv_i_high_pitch, temp_str); 
  353.     GT_SetGadgetAttrs(voice_gads[GAD_HIGH_NOTE], voice_wind, NULL,
  354.         GTST_String, temp_str, TAG_END, 0L);
  355.     GT_SetGadgetAttrs(voice_gads[GAD_MIDI], voice_wind, NULL,
  356.         GTCY_Active, chairs[current_voice].nv_i_audio, TAG_END, 0L);
  357.  
  358.     RefreshGadgets(glist, voice_wind, NULL);
  359.     return;
  360. }
  361.  
  362. int get_current_voice(void)
  363. {
  364.     return current_voice;
  365. }
  366.